package com.xmy.cultivate.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmy.cultivate.entity.*;
import com.xmy.cultivate.entity.views.MelodyConfirm;
import com.xmy.cultivate.enums.StatusSchedulingEnum;
import com.xmy.cultivate.exception.CommonException;
import com.xmy.cultivate.mapper.*;
import com.xmy.cultivate.service.*;
import com.xmy.cultivate.util.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 补课表 服务实现类
 * </p>
 *
 * @author Coly
 * @since 2023-03-07
 */
@Service
public class RepairCourseServiceImpl extends ServiceImpl<RepairCourseMapper, RepairCourse> implements IRepairCourseService {

    @Autowired
    @Lazy
    RepairCourseMapper repairCourseMapper;

    @Autowired
    @Lazy
    CourseSchedulingDetailMapper courseSchedulingDetailMapper;

    @Autowired
    @Lazy
    RecordCourseMapper recordCourseMapper;

    @Autowired
    @Lazy
    CourseMapper courseMapper;

    @Autowired
    @Lazy
    ClassRoomMapper classRoomMapper;

    @Autowired
    @Lazy
    IdWorker idWorker;

    @Autowired
    @Lazy
    StaffMapper staffMapper;

    @Autowired
    @Lazy
    GradeMapper gradeMapper;

    @Autowired
    @Lazy
    SubjectsMapper subjectsMapper;

    @Autowired
    @Lazy
    StudentMapper studentMapper;

    @Autowired
    @Lazy
    OrganizationMapper organizationMapper;

    @Autowired
    @Lazy
    ILackCourseLogService iLackCourseLogService;

    @Autowired
    @Lazy
    IOrderDetailService iOrderDetailService;

    @Autowired
    @Lazy
    IQuarterService iQuarterService;

    @Autowired
    @Lazy
    IStudentGradeService iStudentGradeService;

    @Autowired
    @Lazy
    ICourseSchedulingDetailService iCourseSchedulingDetailService;

    @Autowired
    @Lazy
    IStudentService iStudentService;

    @Autowired
    HolidayMapper holidayMapper;

    /**
     *
     * @param schedulingId
     * @param recordCourseId
     * @param courseType 3安排请假补课，6安排缺课补课
     * @param lessonNum  学生课次（第几次课）
     * @return
     */
    @Transactional
    public boolean insertTo(Long schedulingId,Long recordCourseId,Integer courseType,Long repairId,Integer lessonNum){
        repairCourseMapper.deleteByRecordCourseId(recordCourseId);
        CourseSchedulingDetail courseSchedulingDetail = courseSchedulingDetailMapper.selectById(schedulingId);
        RepairCourse repairCourse = new RepairCourse();
        repairCourse.setLessonType(courseSchedulingDetail.getLessonType());
        repairCourse.setSchoolId(courseSchedulingDetail.getSchoolId());
        repairCourse.setSchedulingDetailId(courseSchedulingDetail.getId());
        repairCourse.setGradeId(courseSchedulingDetail.getGradeId());
        repairCourse.setGradeName(courseSchedulingDetail.getGradeName());
        repairCourse.setSchoolDate(courseSchedulingDetail.getSchoolDate());
        repairCourse.setTimeStart(courseSchedulingDetail.getTimeStart());
        repairCourse.setTimeEnd(courseSchedulingDetail.getTimeEnd());
        repairCourse.setStartDateTime(courseSchedulingDetail.getStartDateTime());
        repairCourse.setEndDateTime(courseSchedulingDetail.getEndDateTime());
        repairCourse.setTeacherId(courseSchedulingDetail.getTeacherId());
        repairCourse.setTeacherName(courseSchedulingDetail.getTeacherName());
        repairCourse.setRoomId(courseSchedulingDetail.getClassRoomId());
        repairCourse.setRoomName(courseSchedulingDetail.getClassRoomName());
        repairCourse.setSubjectsId(courseSchedulingDetail.getSubjectsId());
        repairCourse.setSubjectsName(courseSchedulingDetail.getSubjectsName());
        repairCourse.setYearPart(courseSchedulingDetail.getYearPart());
        repairCourse.setQuarter(courseSchedulingDetail.getQuarter());
        repairCourse.setRepairType(1);//1插班补课，2日程补课
        repairCourse.setCourseType(courseType);
        repairCourse.setLessonNum(lessonNum);//课次
        //repairCourse.setDeleted(courseSchedulingDetail.getDeleted());
        //repairCourse.setCreatedAt(courseSchedulingDetail.getCreatedAt());
        //repairCourse.setUpdatedAt(courseSchedulingDetail.getUpdatedAt());
        //repairCourse.setDeletedAt(courseSchedulingDetail.getDeletedAt());

        repairCourse.setId(repairId);
        repairCourse.setRecordCourseId(recordCourseId);

        //3安排请假补课，6安排缺课补课
        if (courseType.equals(3)){
            RecordCourse recordCourse = recordCourseMapper.select(recordCourseId);
            repairCourse.setStudentId(recordCourse.getStudentId());
            recordCourse.setIsRepair(2);
            recordCourse.setRepairId(repairCourse.getId());
            recordCourse.setRepairEndDateTime(courseSchedulingDetail.getEndDateTime());
            recordCourseMapper.updateById(recordCourse);

        }else if (courseType.equals(6)){
            LackCourseLog lackCourseLog = iLackCourseLogService.getById(recordCourseId);
            repairCourse.setStudentId(lackCourseLog.getStudentId());
            lackCourseLog.setIsRepair(2);
            lackCourseLog.setRepairId(repairCourse.getId());
            lackCourseLog.setRepairEndDateTime(courseSchedulingDetail.getEndDateTime());
            iLackCourseLogService.updateById(lackCourseLog);
        }

        StudentGrade studentGrade = iStudentGradeService.getLastOne(repairCourse.getYearPart(),repairCourse.getQuarter(),repairCourse.getSubjectsId(),repairCourse.getStudentId(),1);
        if (studentGrade!=null){
            Grade gradeOld = gradeMapper.selectById(studentGrade.getGradeId());
            repairCourse.setYearClassId(studentGrade.getYearClassId());
            repairCourse.setOldGradeId(studentGrade.getGradeId());
            repairCourse.setOldTeacherId(gradeOld.getTeacherId());
        }

        repairCourseMapper.insert(repairCourse);


        return true;
    }

    /**
     *
     * @param
     * @param recordCourseId
     * @param schooleDate
     * @param timeStart
     * @param timeEnd
     * @param courseType 3安排请假补课，6安排缺课补课
     * @param lessonNum  学生课次（第几次课）
     * @return
     */
    @Transactional
    public boolean insertIn(Long gradeId,Long teacherId, Long recordCourseId, String schooleDate,String timeStart, String timeEnd,Integer courseType,Long repairId,Integer lessonNum){
        RecordCourse recordCourse = new RecordCourse();
        LackCourseLog lackCourseLog = new LackCourseLog();
        Integer lessonType = null;
        String gradeName = "";
        Integer yearPart = null;
        Integer quarterNum = null;
        Long schoolId = null;
        Long classRoomId = null;
        Long subjectsId = null;

        if (courseType.equals(3)){
            recordCourse = recordCourseMapper.select(recordCourseId);
            lessonType = recordCourse.getLessonType();
            yearPart = recordCourse.getYearPart();
            quarterNum = recordCourse.getQuarter();
            schoolId = recordCourse.getSchoolId();
            subjectsId = recordCourse.getSubjectsId();
        }else if (courseType.equals(6)){
            lackCourseLog = iLackCourseLogService.getById(recordCourseId);
            lessonType = lackCourseLog.getLessonType();
            yearPart = lackCourseLog.getYearPart();
            quarterNum = lackCourseLog.getQuarterNum();
            schoolId = lackCourseLog.getSchoolId();
            subjectsId = lackCourseLog.getSubjectsId();
        }
        //删除之间按排过期的数据
        repairCourseMapper.deleteByRecordCourseId(recordCourseId);

        if (gradeId != null){
            Grade grade = gradeMapper.selectById(gradeId);
            if (grade!=null){
                gradeName = grade.getName();
                classRoomId = grade.getClassRoomId();
                teacherId = grade.getTeacherId();//暂时使用的，后面取消
            }
        }



        //Course course = courseMapper.selectById(grade.getCourseId());
        //ClassRoom classRoomInfo = classRoomMapper.selectById(grade.getClassRoomId());
        //Subjects subjectsInfo = subjectsMapper.selectById(course.getSubjectsId());

        RepairCourse repairCourse = new RepairCourse();
        repairCourse.setLessonType(lessonType);
        repairCourse.setSchedulingDetailId(0L);
        repairCourse.setGradeId(gradeId);
        repairCourse.setGradeName(gradeName);
        repairCourse.setSchoolDate(LocalDate.parse(schooleDate));
        repairCourse.setTimeStart(timeStart);
        repairCourse.setTimeEnd(timeEnd);
        LocalDate localDate = LocalDate.parse(schooleDate);
        LocalTime startTime = LocalTime.parse(timeStart);
        LocalTime endTime = LocalTime.parse(timeEnd);
        repairCourse.setStartDateTime(LocalDateTime.of(localDate,startTime));
        repairCourse.setEndDateTime(LocalDateTime.of(localDate,endTime));
        repairCourse.setTeacherId(teacherId);
        Staff staff = staffMapper.selectById(teacherId);
        if (staff!=null){
            repairCourse.setTeacherName(staff.getName());
        }
        repairCourse.setSchoolId(schoolId);
        repairCourse.setRoomId(classRoomId);
        repairCourse.setYearPart(yearPart);
        repairCourse.setQuarter(quarterNum);
        repairCourse.setCourseType(courseType);//3补课，4调课，5消课
        repairCourse.setRepairType(2);//1插班补课，2日程补课

        if(!Objects.equals(classRoomId,null)){
            ClassRoom classRoom = classRoomMapper.selectById(classRoomId);
            if(!Objects.equals(classRoom,null))
                repairCourse.setRoomName(classRoom.getName());
        }
        repairCourse.setSubjectsId(subjectsId);
        if(subjectsId !=null){
            repairCourse.setSubjectsName(CommonUtil.getSubjectsNameForId(Integer.parseInt(subjectsId.toString())));
        }
        //repairCourse.setDeleted(grade.getDeleted());
        //repairCourse.setCreatedAt(grade.getCreatedAt());
        //repairCourse.setUpdatedAt(grade.getUpdatedAt());
        //repairCourse.setDeletedAt(grade.getDeletedAt());
        repairCourse.setId(repairId);
        repairCourse.setRecordCourseId(recordCourseId);
        repairCourse.setLessonNum(lessonNum);//课次

        /**
         * 不等于精品课
         */
        /*if (!repairCourse.getLessonType().equals(1)){
            //获取精品课最后一次所在班级
            StudentGrade studentGrade = iStudentGradeService.getLastStudentGradeForOrderDetailId(repairCourse.getSchoolId(),studentId,repairCourse.getSubjectsId(),repairCourse.getYearPart(),repairCourse.getQuarter(),1);
            if (studentGrade!=null){
                repairCourse.setYearClassId(studentGrade.getYearClassId());
                repairCourse.setOldGradeId(studentGrade.getGradeId());
            }
        }else {
            repairCourse.setOldGradeId(courseSchedulingDetailOut.getGradeId());
            Grade grade = gradeMapper.selectById(courseSchedulingDetailOut.getGradeId());
            if (grade!=null){
                repairCourse.setYearClassId(grade.getYearClassId().getKey());
            }
        }*/



        //3安排请假补课，6安排缺课补课
        if (courseType.equals(3)){
            repairCourse.setStudentId(recordCourse.getStudentId());
            recordCourse.setIsRepair(2);
            recordCourse.setRepairId(repairCourse.getId());
            recordCourse.setRepairEndDateTime(repairCourse.getEndDateTime());
            recordCourseMapper.updateById(recordCourse);

        }else if (courseType.equals(6)){
            repairCourse.setStudentId(lackCourseLog.getStudentId());
            lackCourseLog.setIsRepair(2);
            lackCourseLog.setRepairId(repairCourse.getId());
            lackCourseLog.setRepairEndDateTime(repairCourse.getEndDateTime());
            iLackCourseLogService.updateById(lackCourseLog);
        }

        StudentGrade studentGrade = iStudentGradeService.getLastOne(repairCourse.getYearPart(),repairCourse.getQuarter(),repairCourse.getSubjectsId(),repairCourse.getStudentId(),1);
        if (studentGrade!=null){
            Grade gradeOld = gradeMapper.selectById(studentGrade.getGradeId());
            repairCourse.setYearClassId(studentGrade.getYearClassId());
            repairCourse.setOldGradeId(studentGrade.getGradeId());
            repairCourse.setOldTeacherId(gradeOld.getTeacherId());
        }

        repairCourseMapper.insert(repairCourse);

        return true;
    }
    public boolean existScheduling(Long schedulingId){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("scheduling_detail_id",schedulingId);
        if(repairCourseMapper.exists(queryWrapper)){
            return true;
        }
        else{
            return false;
        }
    }

    public boolean existClash(RecordCourse recordCourse , Date startDate , Date endDate,Integer courseType,Integer yearPart,Integer quarterNum) throws ParseException {
        //Integer courseType = 3; //3补课，4调课，5消课
        List<RepairCourse> repairCourseList = repairCourseMapper.selectByStudent(recordCourse.getStudentId(),courseType,yearPart,quarterNum);
        for(RepairCourse repairCourse : repairCourseList) {
            String s = String.valueOf(Date.from(repairCourse.getStartDateTime().atZone(ZoneId.systemDefault()).toInstant()).getTime());
            String d = String.valueOf(Date.from(repairCourse.getEndDateTime().atZone(ZoneId.systemDefault()).toInstant()).getTime());
            Date startDateD = new SimpleDateFormat("HH:mm").parse(s);
            Date endDateD = new SimpleDateFormat("HH:mm").parse(d);
            if((startDate.compareTo(startDateD) < 0 && startDate.compareTo(endDateD) > 0) || startDate.equals(startDateD) || endDate.equals(endDateD))
                return true;
        }
        return false;
    }


    /**
     *
     * @param schoolId
     * @param outDate 转出日期
     * @param inDate 转入日期
     * @param lessonType
     * @param type 1正常排课，2调课
     * @throws ParseException
     */
    @Override
    @Async("onlineAsync")
    public void melodyCourseForGradeBatch(Long schoolId, LocalDate outDate, LocalDate inDate, Integer lessonType, Integer type) throws ParseException {
        QueryWrapper<CourseSchedulingDetail> queryWrapper = new QueryWrapper<>();
        if (schoolId != null){
            queryWrapper.eq("school_id",schoolId);
        }
        queryWrapper.eq("school_date",outDate);
        queryWrapper.in("status",0,2);
        if (lessonType !=null){
            queryWrapper.eq("lesson_type",lessonType);
        }
        if (type !=null){
            queryWrapper.eq("type",type);
        }

        List<CourseSchedulingDetail> courseSchedulingDetailList = courseSchedulingDetailMapper.selectList(queryWrapper);
        for (CourseSchedulingDetail courseSchedulingDetail : courseSchedulingDetailList) {
            try {
                courseSchedulingDetail.setSchoolDate(inDate);
                this.melodyCourseForGrade(courseSchedulingDetail);
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
        }
    }


    /**
     * 按班级调课
     * @param courseSchedulingDetail
     * @return
     * @throws ParseException
     */
    @Transactional
    public boolean melodyCourseForGrade(CourseSchedulingDetail courseSchedulingDetail) throws ParseException {
        CourseSchedulingDetail courseSchedulingDetailOld = courseSchedulingDetailMapper.selectById(courseSchedulingDetail.getId());
        if (courseSchedulingDetailOld == null){
            throw new CommonException(ResultCode.NOTDATA);
        }

        CourseSchedulingDetail courseSchedulingDetailNew  = new CourseSchedulingDetail();
        //复制内容
        BeanUtils.copyProperties(courseSchedulingDetailOld,courseSchedulingDetailNew);
        courseSchedulingDetailNew.setId(idWorker.nextId());
        courseSchedulingDetailNew.setDeleted(1);


        //courseSchedulingDetailNew.setClassRoomId(courseSchedulingDetail.getClassRoomId());
        courseSchedulingDetailMapper.insert(courseSchedulingDetailNew);
        //courseSchedulingDetailMapper.deleteById(courseSchedulingDetailOld.getId());

        courseSchedulingDetailOld.setPid(courseSchedulingDetailNew.getId());
        courseSchedulingDetailOld.setSchoolDate(courseSchedulingDetail.getSchoolDate());
        LocalDateTime startDateTime = DateUtil.StrToDateTime(courseSchedulingDetail.getSchoolDate() + "T"+ courseSchedulingDetail.getTimeStart()+":00");
        LocalDateTime endDateTime = DateUtil.StrToDateTime(courseSchedulingDetail.getSchoolDate() + "T"+ courseSchedulingDetail.getTimeEnd()+":00");

        courseSchedulingDetailOld.setStartDateTime(startDateTime);
        courseSchedulingDetailOld.setEndDateTime(endDateTime);
        courseSchedulingDetailOld.setTimeStart(courseSchedulingDetail.getTimeStart());
        courseSchedulingDetailOld.setTimeEnd(courseSchedulingDetail.getTimeEnd());
        courseSchedulingDetailOld.setUseLeaveNum(courseSchedulingDetail.getUseLeaveNum());

        courseSchedulingDetailOld.setType(2);//1正常排课，2调课
        courseSchedulingDetailOld.setStatus(StatusSchedulingEnum.NO);
        courseSchedulingDetailMapper.updateById(courseSchedulingDetailOld);


        //UpdateWrapper<RepairCourse> repairCourseUpdateWrapper = new UpdateWrapper<>();
        //repairCourseUpdateWrapper.set("scheduling_detail_id",courseSchedulingDetailNew.getId()).eq("scheduling_detail_id",courseSchedulingDetailOld.getId());
        //repairCourseMapper.update(null,repairCourseUpdateWrapper);

        //repairCourseUpdateWrapper = new UpdateWrapper<>();
        //repairCourseUpdateWrapper.set("out_scheduling_detail_id",courseSchedulingDetailNew.getId()).eq("out_scheduling_detail_id",courseSchedulingDetailOld.getId());
        //repairCourseMapper.update(null,repairCourseUpdateWrapper);

        return true;
    }

    /**
     * 删除按班级调课
     * @param
     * @return
     * @throws ParseException
     */
    @Transactional
    public boolean deleteMelodyCourseForGrade(Long id) throws ParseException {
        CourseSchedulingDetail courseSchedulingDetail = courseSchedulingDetailMapper.selectById(id);

        if (courseSchedulingDetail == null){
            throw new CommonException(ResultCode.NOTDATA);
        }

        if (courseSchedulingDetail.getStatus().equals(StatusSchedulingEnum.ON)){
            throw new CommonException(ResultCode.NOT_DELETE_REPAIR);
        }

        //恢复原来数据
        //courseSchedulingDetailMapper.unDeleteForId(courseSchedulingDetail.getPid());
        //原来的数据
        //CourseSchedulingDetail courseSchedulingDetailOld = courseSchedulingDetailMapper.selectById(courseSchedulingDetail.getPid());
        //UpdateWrapper<RepairCourse> repairCourseUpdateWrapper = new UpdateWrapper<>();
        //repairCourseUpdateWrapper.set("scheduling_detail_id",courseSchedulingDetail.getPid()).eq("scheduling_detail_id",courseSchedulingDetail.getId());
        //repairCourseMapper.update(null,repairCourseUpdateWrapper);
        //courseSchedulingDetailMapper.deleteById(courseSchedulingDetail.getId());
        CourseSchedulingDetail courseSchedulingDetailDelete = courseSchedulingDetailMapper.getOneAndDeleted(courseSchedulingDetail.getPid());
        if (courseSchedulingDetailDelete == null){
            throw new CommonException(ResultCode.NOTDATA);
        }
        courseSchedulingDetail.setSchoolDate(courseSchedulingDetailDelete.getSchoolDate());
        courseSchedulingDetail.setTimeStart(courseSchedulingDetailDelete.getTimeStart());
        courseSchedulingDetail.setTimeEnd(courseSchedulingDetailDelete.getTimeEnd());
        courseSchedulingDetail.setStartDateTime(courseSchedulingDetailDelete.getStartDateTime());
        courseSchedulingDetail.setEndDateTime(courseSchedulingDetailDelete.getEndDateTime());
        courseSchedulingDetail.setStatus(courseSchedulingDetailDelete.getStatus());
        courseSchedulingDetail.setPid(0L);
        courseSchedulingDetail.setType(1);
        courseSchedulingDetail.setUseLeaveNum(0);
        courseSchedulingDetailMapper.updateById(courseSchedulingDetail);

        return true;
    }


    @Override
    public  MelodyConfirm melodyCourseForStudentConfirm(RepairCourse repairCourse, Long adminId){

        LocalDateTime dateTimeNow = LocalDateTime.now().withNano(0);

        CourseSchedulingDetail outCourseSchedulingDetail = iCourseSchedulingDetailService.getById(repairCourse.getOutSchedulingDetailId());

        MelodyConfirm melodyConfirm = new MelodyConfirm();

        //精品课停课，或者非精品课不做请假次数计算
        if ((outCourseSchedulingDetail.getStatus().equals(StatusSchedulingEnum.STOP) && outCourseSchedulingDetail.getLessonType().equals(1)) || !outCourseSchedulingDetail.getLessonType().equals(1)){
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);
            melodyConfirm.setMsg("");
            return melodyConfirm;
        }
        LocalDate outDate = LocalDate.from(outCourseSchedulingDetail.getStartDateTime());
        Integer isHoliDay = holidayMapper.getIsAt(outDate,2);

        //超级管理员添加，不做请假次数计算
        if (adminId.equals(1568138350324350975L) || isHoliDay > 0){
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);
            melodyConfirm.setMsg("");
            return melodyConfirm;
        }


        Integer lessonType = outCourseSchedulingDetail.getLessonType();
        String startDateTime=null;
        if (repairCourse.getSchedulingDetailId()!=null){
            CourseSchedulingDetail courseSchedulingDetail = iCourseSchedulingDetailService.getById(repairCourse.getSchedulingDetailId());
            if (courseSchedulingDetail!=null){
                startDateTime = courseSchedulingDetail.getStartDateTime().toString();
            }
        }else {
            startDateTime = repairCourse.getSchoolDate() + "T" + repairCourse.getTimeStart() + ":00";
        }

        List<String> studentNameList = new ArrayList<>();

        /*if (outCourseSchedulingDetail.getLessonType().equals(1) && outCourseSchedulingDetail.getStartDateTime().isBefore(LocalDateTime.parse(startDateTime))){
            //调课开始上课时间不能大于原来的上课时间
            List<String> allStudentNameList = new ArrayList<>();
            for (Long studentId:repairCourse.getStudentIdList()){
                Student student =iStudentService.getById(studentId);
                Integer leaveCount = recordCourseMapper.getUseLeaveCount(outCourseSchedulingDetail.getYearPart(),outCourseSchedulingDetail.getQuarter(),studentId,outCourseSchedulingDetail.getSubjectsId(),lessonType,dateTimeNow.toString());
                if (leaveCount>=2){
                    studentNameList.add(student.getName());
                }
                allStudentNameList.add(student.getName());
            }
            if (studentNameList.size()>0){
                String studentNames = studentNameList.stream().collect(Collectors.joining(","));
                melodyConfirm.setStatus(0);//有请假次数已经大于等于2
                melodyConfirm.setType(1);//需要扣减请假课次
                melodyConfirm.setMsg(studentNames+";请假次数已经大于等于2,不能再安排调课上课时间在调出上课时间之后");

            }else {
                String allStudentNameStr = allStudentNameList.stream().collect(Collectors.joining(","));
                melodyConfirm.setStatus(1);
                melodyConfirm.setType(1);//需要扣减请假课次
                melodyConfirm.setMsg(allStudentNameStr);
            }
        }else {
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);//不需要扣减请假课次
            melodyConfirm.setMsg("");
        }*/


        if (outCourseSchedulingDetail.getLessonType().equals(1) && outCourseSchedulingDetail.getStartDateTime().isBefore(LocalDateTime.parse(startDateTime))){
            melodyConfirm.setStatus(0);
            melodyConfirm.setType(0);//不需要扣减请假课次
            melodyConfirm.setMsg("上课时间不能大于调出时间："+outCourseSchedulingDetail.getStartDateTime().toString().replace("T"," "));
        }else if(outCourseSchedulingDetail.getLessonType().equals(1)){
            //往前调课的也算用掉一次请假机会
            List<String> allStudentNameList = new ArrayList<>();
            for (Long studentId:repairCourse.getStudentIdList()){
                Student student =iStudentService.getById(studentId);
                allStudentNameList.add(student.getName());
            }
            String allStudentNameStr = allStudentNameList.stream().collect(Collectors.joining(","));
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(1);//需要扣减请假课次
            melodyConfirm.setMsg(allStudentNameStr);
        } else{
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);//需要扣减请假课次
            melodyConfirm.setMsg("");
        }

        return melodyConfirm;
    }

    @Override
    public MelodyConfirm

    melodyCourseForGradeConfirm(CourseSchedulingDetail inCourseSchedulingDetail, CourseSchedulingDetail outCourseSchedulingDetail, Long adminId) throws ParseException {

        MelodyConfirm melodyConfirm = new MelodyConfirm();

        LocalDateTime dateTimeNow = LocalDateTime.now().withNano(0);

        //精品课停课，或者非精品课不做请假次数计算
        if ((outCourseSchedulingDetail.getStatus().equals(StatusSchedulingEnum.STOP) && outCourseSchedulingDetail.getLessonType().equals(1)) || !outCourseSchedulingDetail.getLessonType().equals(1)){
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);
            melodyConfirm.setMsg("");
            return melodyConfirm;
        }

        LocalDate outDate = LocalDate.from(outCourseSchedulingDetail.getStartDateTime());
        Integer isHoliDay = holidayMapper.getIsAt(outDate,2);

        //超级管理员添加，不做请假次数计算
        if (adminId.equals(1568138350324350975L) || isHoliDay > 0){
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);
            melodyConfirm.setMsg("");
            return melodyConfirm;
        }

        Integer lessonType = outCourseSchedulingDetail.getLessonType();

        List<String> studentNameList = new ArrayList<>();
        List<String> allStudentNameList = new ArrayList<>();
        LocalDateTime startDateTime = DateUtil.StrToDateTime(inCourseSchedulingDetail.getSchoolDate() + "T"+ inCourseSchedulingDetail.getTimeStart()+":00");
        //LocalDateTime endDateTime = DateUtil.StrToDateTime(inCourseSchedulingDetail.getSchoolDate() + "T"+ inCourseSchedulingDetail.getTimeEnd()+":00");


        /*if (outCourseSchedulingDetail.getLessonType().equals(1) && outCourseSchedulingDetail.getStartDateTime().isBefore(startDateTime)){
            QueryWrapper<StudentGrade> studentGradeQueryWrapper = new QueryWrapper<>();
            studentGradeQueryWrapper.eq("grade_id",outCourseSchedulingDetail.getGradeId());
            studentGradeQueryWrapper.eq("status",1);
            studentGradeQueryWrapper.eq("reading_status",1);
            studentGradeQueryWrapper.notInSql("student_id","select student_id from repair_course where out_scheduling_detail_id ="+outCourseSchedulingDetail.getId()+" and deleted =0");
            List<StudentGrade> studentGradeList = iStudentGradeService.list(studentGradeQueryWrapper);
            for (StudentGrade studentGrade:studentGradeList){
                Long studentId = studentGrade.getStudentId();
                Student student =iStudentService.getById(studentId);
                Integer leaveCount = recordCourseMapper.getUseLeaveCount(outCourseSchedulingDetail.getYearPart(),outCourseSchedulingDetail.getQuarter(),studentId,outCourseSchedulingDetail.getSubjectsId(),lessonType,dateTimeNow.toString());
                if (leaveCount>=2){
                    studentNameList.add(student.getName());
                }
                allStudentNameList.add(student.getName());
            }
            if (studentNameList.size()>0){
                String studentNames = studentNameList.stream().collect(Collectors.joining(","));
                melodyConfirm.setStatus(0);//有请假次数已经大于等于2
                melodyConfirm.setType(1);//需要扣减请假课次
                melodyConfirm.setMsg(studentNames+";请假次数已经大于等于2,不能再安排调课上课时间在调出上课时间之后");

            }else {
                String allStudentNameStr = allStudentNameList.stream().collect(Collectors.joining(","));
                melodyConfirm.setStatus(1);
                melodyConfirm.setType(1);//需要扣减请假课次
                melodyConfirm.setMsg(allStudentNameStr);
            }
        }else {
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);//需要扣减请假课次
            melodyConfirm.setMsg("");
        }*/

        if (outCourseSchedulingDetail.getLessonType().equals(1) && outCourseSchedulingDetail.getStartDateTime().isBefore(startDateTime)) {
            melodyConfirm.setStatus(0);
            melodyConfirm.setType(0);//需要扣减请假课次
            melodyConfirm.setMsg("上课时间不能大于调出时间："+outCourseSchedulingDetail.getStartDateTime().toString().replace("T"," "));
        }else if (outCourseSchedulingDetail.getLessonType().equals(1)){
            //往前调课的也算用掉一次请假机会
            QueryWrapper<StudentGrade> studentGradeQueryWrapper = new QueryWrapper<>();
            studentGradeQueryWrapper.eq("grade_id",outCourseSchedulingDetail.getGradeId());
            studentGradeQueryWrapper.eq("status",1);
            studentGradeQueryWrapper.eq("reading_status",1);
            studentGradeQueryWrapper.notInSql("student_id","select student_id from repair_course where out_scheduling_detail_id ="+outCourseSchedulingDetail.getId()+" and deleted =0");
            List<StudentGrade> studentGradeList = iStudentGradeService.list(studentGradeQueryWrapper);
            for (StudentGrade studentGrade:studentGradeList){
                Long studentId = studentGrade.getStudentId();
                Student student =iStudentService.getById(studentId);
                allStudentNameList.add(student.getName());
            }
            String allStudentNameStr = allStudentNameList.stream().collect(Collectors.joining(","));
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(1);//需要扣减请假课次
            melodyConfirm.setMsg(allStudentNameStr);
        }else {
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);
            melodyConfirm.setMsg("");
        }
/*        //原来
        if (outCourseSchedulingDetail.getLessonType().equals(1) && outCourseSchedulingDetail.getStartDateTime().isBefore(startDateTime)) {
            melodyConfirm.setStatus(0);
            melodyConfirm.setType(0);//需要扣减请假课次
            melodyConfirm.setMsg("上课时间不能大于调出时间："+outCourseSchedulingDetail.getStartDateTime().toString().replace("T"," "));
        }else {
            melodyConfirm.setStatus(1);
            melodyConfirm.setType(0);//需要扣减请假课次
            melodyConfirm.setMsg("");
        }*/


            return melodyConfirm;
    }



    /**
     * 按学员调课
     * @param repairCourse
     * @return
     * @throws ParseException
     */
    @Transactional
    public boolean melodyCourseForStudent(RepairCourse repairCourse) throws ParseException{

        //被调出的排课
        CourseSchedulingDetail courseSchedulingDetailOut = courseSchedulingDetailMapper.selectById(repairCourse.getOutSchedulingDetailId());

        /**
         * 1插班调课，2日程调课
         */
        if (repairCourse.getRepairType().equals(1)){
            //插班调课
            CourseSchedulingDetail courseSchedulingDetail = courseSchedulingDetailMapper.selectById(repairCourse.getSchedulingDetailId());
            if(courseSchedulingDetail == null){
                throw new CommonException(ResultCode.CourseScheduling);
            }
            for (Long studentId:repairCourse.getStudentIdList()){
                RepairCourse repairCourseData = new RepairCourse();
                BeanUtils.copyProperties(courseSchedulingDetail,repairCourseData);

                repairCourseData.setId(idWorker.nextId());
                repairCourseData.setStudentId(studentId);
                repairCourseData.setSchedulingDetailId(repairCourse.getSchedulingDetailId());
                repairCourseData.setOutSchedulingDetailId(repairCourse.getOutSchedulingDetailId());
                repairCourseData.setCourseType(4);//3补课，4调课，5消课
                repairCourseData.setRepairType(repairCourse.getRepairType());//1插班调课，2日程调课
                repairCourseData.setUseLeaveNum(repairCourse.getUseLeaveNum());
                repairCourseData.setOldGradeId(courseSchedulingDetailOut.getGradeId());
                repairCourseData.setCreatedAt(LocalDateTime.now().withNano(0));


                //获取精品课最后一次所在班级
                StudentGrade studentGrade = iStudentGradeService.getLastStudentGradeForOrderDetailId(courseSchedulingDetailOut.getSchoolId(),studentId,courseSchedulingDetailOut.getSubjectsId(),courseSchedulingDetailOut.getYearPart(),courseSchedulingDetailOut.getQuarter(),1);
                if (studentGrade!=null){
                    Grade gradeOld = gradeMapper.selectById(studentGrade.getGradeId());
                    repairCourseData.setYearClassId(studentGrade.getYearClassId());
                    repairCourseData.setOldGradeId(studentGrade.getGradeId());
                    repairCourseData.setOldTeacherId(gradeOld.getTeacherId());
                }

                repairCourseMapper.insert(repairCourseData);
            }
        }else {
            CourseSchedulingDetail courseSchedulingDetail = courseSchedulingDetailMapper.selectById(repairCourse.getOutSchedulingDetailId());
            if (courseSchedulingDetail == null){
                throw new CommonException(ResultCode.CourseScheduling);
            }
            LocalDateTime startDateTime = DateUtil.StrToDateTime(repairCourse.getSchoolDate() + "T"+ repairCourse.getTimeStart()+":00");
            LocalDateTime endDateTime = DateUtil.StrToDateTime(repairCourse.getSchoolDate() + "T"+ repairCourse.getTimeEnd()+":00");

            Staff teacherInfo = null;
            if (repairCourse.getTeacherId() != null){
                    teacherInfo = staffMapper.selectById(repairCourse.getTeacherId());
            }else {
                Grade grade = gradeMapper.selectById(repairCourse.getGradeId());
                if (grade != null){
                    teacherInfo = staffMapper.selectById(grade.getTeacherId());
                    repairCourse.setTeacherId(grade.getTeacherId());
                    repairCourse.setTeacherName(teacherInfo.getName());
                }
            }
             /*if (grade == null){
                throw new CommonException(ResultCode.GRADE_NOT);
            }
           Course course = courseMapper.selectById(grade.getCourseId());
            if (course == null){
                throw new CommonException(ResultCode.COURSE_NOT);
            }*/

            if (teacherInfo == null){
                throw new CommonException(ResultCode.TeacerNo);
            }
            //ClassRoom classRoomInfo = classRoomMapper.selectById(grade.getClassRoomId());
            Subjects subjectsInfo = subjectsMapper.selectById(courseSchedulingDetail.getSubjectsId());

            //日程调课
            for (Long studentId:repairCourse.getStudentIdList()){
                RepairCourse repairCourseData = new RepairCourse();
                repairCourseData.setId(idWorker.nextId());
                repairCourseData.setLessonType(courseSchedulingDetail.getLessonType());
                repairCourseData.setSchedulingDetailId(repairCourse.getSchedulingDetailId());
                repairCourseData.setOutSchedulingDetailId(repairCourse.getOutSchedulingDetailId());
                repairCourseData.setSchoolId(courseSchedulingDetail.getSchoolId());
                repairCourseData.setStudentId(studentId);
                repairCourseData.setGradeId(repairCourse.getGradeId());
                //repairCourseData.setGradeName(grade.getName());
                repairCourseData.setSchoolDate(repairCourse.getSchoolDate());
                repairCourseData.setTimeStart(repairCourse.getTimeStart());
                repairCourseData.setTimeEnd(repairCourse.getTimeEnd());
                repairCourseData.setStartDateTime(startDateTime);
                repairCourseData.setEndDateTime(endDateTime);
                repairCourseData.setTeacherId(repairCourse.getTeacherId());
                repairCourseData.setTeacherName(teacherInfo.getName());
                //repairCourseData.setRoomId(grade.getClassRoomId());
                /*if (classRoomInfo != null){
                    repairCourseData.setRoomName(classRoomInfo.getName());
                }*/
                repairCourseData.setLessonNum(courseSchedulingDetail.getLessonNum());
                repairCourseData.setSubjectsId(courseSchedulingDetail.getSubjectsId());
                if (subjectsInfo != null){
                    repairCourseData.setSubjectsName(subjectsInfo.getName());
                }
                repairCourseData.setCourseType(4);//3补课，4调课，5消课
                repairCourseData.setRepairType(repairCourse.getRepairType());//1插班调课，2日程调课
                repairCourseData.setYearPart(courseSchedulingDetail.getYearPart());
                repairCourseData.setQuarter(courseSchedulingDetail.getQuarter());
                repairCourseData.setUseLeaveNum(repairCourse.getUseLeaveNum());

                //获取精品课最后一次所在班级
                //StudentGrade studentGrade = iStudentGradeService.getLastStudentGradeForOrderDetailId(courseSchedulingDetailOut.getSchoolId(),studentId,courseSchedulingDetailOut.getSubjectsId(),courseSchedulingDetailOut.getYearPart(),courseSchedulingDetailOut.getQuarter(),1);
                StudentGrade studentGrade = iStudentGradeService.getLastOne(courseSchedulingDetailOut.getYearPart(),courseSchedulingDetailOut.getQuarter(),courseSchedulingDetailOut.getSubjectsId(),studentId,1);
                if (studentGrade!=null){
                    Grade gradeOld = gradeMapper.selectById(studentGrade.getGradeId());
                    repairCourseData.setYearClassId(studentGrade.getYearClassId());
                    repairCourseData.setOldGradeId(studentGrade.getGradeId());
                    repairCourseData.setOldTeacherId(gradeOld.getTeacherId());
                }
                repairCourseMapper.insert(repairCourseData);
            }
        }
        return true;
    }

    /**
     * 消课
     * @param repairCourse
     * @return
     * @throws ParseException
     */
    @Transactional
    public boolean consumeCoruse(RepairCourse repairCourse) throws ParseException {

        /**
         * 1插班调课，2日程调课
         */
        if (repairCourse.getRepairType().equals(1)){
            //插班消课
            CourseSchedulingDetail courseSchedulingDetail = courseSchedulingDetailMapper.selectById(repairCourse.getSchedulingDetailId());
            if(courseSchedulingDetail == null){
                throw new CommonException(ResultCode.CourseScheduling);
            }

            for (Long studentId:repairCourse.getStudentIdList()){
                RepairCourse repairCourseData = new RepairCourse();
                repairCourseData.setId(idWorker.nextId());
                repairCourseData.setLessonType(courseSchedulingDetail.getLessonType());
                //repairCourseData.setSchedulingDetailId(repairCourse.getSchedulingDetailId());
                repairCourseData.setOrderDetailId(repairCourse.getOrderDetailId());
                repairCourseData.setSchoolId(courseSchedulingDetail.getSchoolId());
                repairCourseData.setStudentId(studentId);
                repairCourseData.setGradeId(courseSchedulingDetail.getGradeId());
                repairCourseData.setGradeName(courseSchedulingDetail.getGradeName());
                repairCourseData.setSchoolDate(courseSchedulingDetail.getSchoolDate());
                repairCourseData.setTimeStart(courseSchedulingDetail.getTimeStart());
                repairCourseData.setTimeEnd(courseSchedulingDetail.getTimeEnd());
                repairCourseData.setStartDateTime(courseSchedulingDetail.getStartDateTime());
                repairCourseData.setEndDateTime(courseSchedulingDetail.getEndDateTime());
                repairCourseData.setTeacherId(courseSchedulingDetail.getTeacherId());
                repairCourseData.setTeacherName(courseSchedulingDetail.getTeacherName());
                repairCourseData.setRoomId(courseSchedulingDetail.getClassRoomId());
                repairCourseData.setRoomName(courseSchedulingDetail.getClassRoomName());
                repairCourseData.setSubjectsId(courseSchedulingDetail.getSubjectsId());
                repairCourseData.setSubjectsName(courseSchedulingDetail.getSubjectsName());
                repairCourseData.setCourseType(5);//3补课，4调课，5消课
                repairCourseData.setRepairType(repairCourse.getRepairType());//1插班调课，2日程调课
                repairCourseData.setYearPart(courseSchedulingDetail.getYearPart());
                repairCourseData.setQuarter(courseSchedulingDetail.getQuarter());

                StudentGrade studentGrade = iStudentGradeService.getLastOne(repairCourseData.getYearPart(),repairCourseData.getQuarter(),repairCourseData.getSubjectsId(),repairCourseData.getStudentId(),1);
                if (studentGrade!=null){
                    Grade gradeOld = gradeMapper.selectById(studentGrade.getGradeId());
                    repairCourseData.setYearClassId(studentGrade.getYearClassId());
                    repairCourseData.setOldGradeId(studentGrade.getGradeId());
                    repairCourseData.setOldTeacherId(gradeOld.getTeacherId());
                }

                repairCourseMapper.insert(repairCourseData);
            }
        }else {
            //日程调课
            Quarter quarterNow = iQuarterService.getNowQuarter();
            LocalDateTime startDateTime = DateUtil.StrToDateTime(repairCourse.getSchoolDate() + "T"+ repairCourse.getTimeStart()+":00");
            LocalDateTime endDateTime = DateUtil.StrToDateTime(repairCourse.getSchoolDate() + "T"+ repairCourse.getTimeEnd()+":00");

            OrderDetail orderDetail = iOrderDetailService.getById(repairCourse.getOrderDetailId());
            if (orderDetail == null){
                throw new CommonException(ResultCode.NOORDER);
            }

            /*Grade grade = gradeMapper.selectById(repairCourse.getGradeId());
            if (grade == null){
                throw new CommonException(ResultCode.GRADE_NOT);
            }
            Course course = courseMapper.selectById(grade.getCourseId());
            if (course == null){
                throw new CommonException(ResultCode.COURSE_NOT);
            }*/
            Staff teacherInfo = staffMapper.selectById(repairCourse.getTeacherId());
            if (teacherInfo == null){
                throw new CommonException(ResultCode.TeacerNo);
            }
            //ClassRoom classRoomInfo = classRoomMapper.selectById(grade.getClassRoomId());
            Subjects subjectsInfo = subjectsMapper.selectById(orderDetail.getSubjectsId());

            for (Long studentId:repairCourse.getStudentIdList()){
                RepairCourse repairCourseData = new RepairCourse();
                repairCourseData.setId(idWorker.nextId());
                repairCourseData.setLessonType(orderDetail.getLessonType());
                //repairCourseData.setSchedulingDetailId(repairCourse.getSchedulingDetailId());
                repairCourseData.setOrderDetailId(repairCourse.getOrderDetailId());
                repairCourseData.setSchoolId(orderDetail.getSchoolId());
                repairCourseData.setStudentId(studentId);
                repairCourseData.setGradeId(orderDetail.getGradeId());
                repairCourseData.setGradeName(orderDetail.getGradeName());
                repairCourseData.setSchoolDate(repairCourse.getSchoolDate());
                repairCourseData.setTimeStart(repairCourse.getTimeStart());
                repairCourseData.setTimeEnd(repairCourse.getTimeEnd());
                repairCourseData.setStartDateTime(startDateTime);
                repairCourseData.setEndDateTime(endDateTime);
                repairCourseData.setTeacherId(repairCourse.getTeacherId());
                repairCourseData.setTeacherName(teacherInfo.getName());
                /*repairCourseData.setRoomId(grade.getClassRoomId());
                if (classRoomInfo != null){
                    repairCourseData.setRoomName(classRoomInfo.getName());
                }*/
                repairCourseData.setSubjectsId(orderDetail.getSubjectsId());
                if (subjectsInfo != null){
                    repairCourseData.setSubjectsName(subjectsInfo.getName());
                }
                repairCourseData.setCourseType(5);//3补课，4调课，5消课
                repairCourseData.setRepairType(repairCourse.getRepairType());//1插班调课，2日程调课
                repairCourseData.setYearPart(quarterNow.getYearPart());
                repairCourseData.setQuarter(quarterNow.getNum());

                StudentGrade studentGrade = iStudentGradeService.getLastOne(repairCourseData.getYearPart(),repairCourseData.getQuarter(),repairCourseData.getSubjectsId(),repairCourseData.getStudentId(),1);
                if (studentGrade!=null){
                    Grade gradeOld = gradeMapper.selectById(studentGrade.getGradeId());
                    repairCourseData.setYearClassId(studentGrade.getYearClassId());
                    repairCourseData.setOldGradeId(studentGrade.getGradeId());
                    repairCourseData.setOldTeacherId(gradeOld.getTeacherId());
                }

                repairCourseMapper.insert(repairCourseData);
            }
        }
        return true;
    }

    /**
     *按班级调课，查看时间是否宣冲突
     * @param startDateTime
     * @param schoolDate
     * @param gradeId
     * @return
     */
    public Long getClashCountForGrade(String startDateTime,String endDateTime,String schoolDate,Long gradeId,Long id){
        return repairCourseMapper.getClashCountForGrade(startDateTime,endDateTime,schoolDate,gradeId,id);
    }

    /**
     * 按学员调课，查看时间是否宣冲突
     * @param startDateTime
     * @param endDateTime
     * @param studentId
     * @return
     */
    @Override
    public Long getClashCountForStudent(String startDateTime, String endDateTime, Long studentId, Integer lessonType){
        return repairCourseMapper.getClashCountForStudent(startDateTime,endDateTime,studentId,lessonType);
    }

    public IPage<RepairCourse> consumeCourseForStudentList(IPage<RecordCourse> page, Wrapper wrapper){
        IPage<RepairCourse> iPage = repairCourseMapper.consumeCourseForStudentList(page,wrapper);
        for (RepairCourse recordCourse:iPage.getRecords()){
            Student student = studentMapper.selectById(recordCourse.getStudentId());
            if (student!=null){
                recordCourse.setStudentName(student.getName());
            }
            Grade grade = gradeMapper.selectById(recordCourse.getOldGradeId());
            if (grade !=null){
                Course course = courseMapper.selectById(grade.getCourseId());
                if (course !=null){
                    recordCourse.setCourseName(course.getName());
                }
                recordCourse.setGradeName(grade.getName());
            }

            Organization organization = organizationMapper.selectById(recordCourse.getSchoolId());
            if (organization != null){
                recordCourse.setSchoolName(organization.getName());
            }
        }
        return iPage;
    }

    public IPage<RecordCourse> consumeCourseForStudentExcel(IPage<RecordCourse> page, Wrapper wrapper){
        IPage<RecordCourse> iPage = repairCourseMapper.consumeCourseForStudentExcel(page,wrapper);
        for (RecordCourse recordCourse:iPage.getRecords()){
            Student student = studentMapper.selectById(recordCourse.getStudentId());
            if (student!=null){
                recordCourse.setStudentName(student.getName());
            }
            Grade grade = gradeMapper.selectById(recordCourse.getOldGradeId());
            if (grade !=null){
                Course course = courseMapper.selectById(grade.getCourseId());
                if (course !=null){
                    recordCourse.setCourseName(course.getName());
                }
                recordCourse.setGradeName(grade.getName());
            }

            Organization organization = organizationMapper.selectById(recordCourse.getSchoolId());
            if (organization != null){
                recordCourse.setSchoolName(organization.getName());
            }
        }
        return iPage;
    }

    @Override
    public IPage<RepairCourse> getTemporaryClass(IPage<RepairCourse> page, Wrapper wrapper) {
        return repairCourseMapper.getTemporaryClass(page,wrapper);
    }
}
